package com.imdroid.carac.audioCodec;

import java.nio.ByteBuffer;

// jni/ndk native C code
class C {




// opus specification:
// 16bits ( 2 Bytes ) per sample
// valid samples per sec ( sample rate ): 8000, 12000, 16000, 24000, 48000 Hz
// valid milli-sec per frame: 2.5, 5, 10, 20, 40 or 60 ms
// recommend 16000Hz:
//     16 samples per ms, 320 samples per 20ms frame (mono channel)
//     produces stream at about 2.4k bytes per sec
//     the voice quality is good enough
//     while 8000Hz produces sound like a very cheap cell-phone
//     in fact, AMR-WB uses 16kHz to support voice freq 50~7000Hz
//     AMR-NB uses 8000Hz to support voice freq 300~3400Hz

static final int samplesPerSec = 16000;
static final int msPerFrame = 60;
static final int samplesPerFrame = samplesPerSec * msPerFrame / 1000;
static final int encPcmBytes = 2 * samplesPerFrame;
// we can expect that the stream is much smaller than orginal PCM
// use a buffer as large as the above, just in case.
static final int encStreamBytes = encPcmBytes;
// don't know why, but opus says that decode() may produce 120ms PCM at most, so decodePcmBuf should be as large
static final int decPcmBytes = 2 * samplesPerSec * 120 / 1000;
// same reason as encode
static final int decStreamBytes = decPcmBytes;
static final int threadInterval = 10; // ms
// android AudioRecord buf; 2 Bytes per sample, and make it a several times larger
static final int audioRecordBufBytes = 5 * 2 * samplesPerSec * threadInterval / 1000;

static ByteBuffer encPcm;
static ByteBuffer encStream;
static ByteBuffer decPcm;
static ByteBuffer decStream;

static {
	encPcm = ByteBuffer.allocateDirect( encPcmBytes );
	encStream = ByteBuffer.allocateDirect( encStreamBytes );
	decPcm = ByteBuffer.allocateDirect( decPcmBytes );
	decStream = ByteBuffer.allocateDirect( decStreamBytes );
	System.loadLibrary("audio_codec_opus");
	init( samplesPerSec, encPcm, encStream, decPcm, decStream );
}

// opus error code :
// -1 One or more invalid of range arguments
// -2 The mode struct passed is invalid
// -3 An internal error was detected
// -4 The compressed data passed is corrupted
// -5 Invalid request number
// -6 An encoder or decoder structure is invalid or already freed
// -7 Memory allocation has failed

// return : 0 OK, opus error code
native static int init( int samplesPerSec_a, ByteBuffer encPcm_a, ByteBuffer encStream_a, ByteBuffer decPcm_a, ByteBuffer decStream_a );

native static void encReset();

native static void decReset();

// return: >= 0 actual bytes in stream; < 0 opus error code
native static int enc();

// bytes: actual bytes in stream
// return: >= 0 samples produced; < 0 opus error code
native static int dec( int bytes );

native static void release();




}
